<?php
namespace Core\Libs\MasterObject;
/*
class MasterObjectException {

	
}
*/
class MasterObject  {

	public static $arrayMethodsAllowed = array();
	protected static $arrayNotResetProperties = array();

	private static $ObjectStack = NULL;
	private static $Registry = NULL;
	private static $Reflection = NULL;
	private static $Cast = NULL;
	private static $Http = NULL;
	private static $Encrypt = NULL;
	private static $Decrypt = NULL;
	private static $Request = NULL;
	private static $Message = NULL;
	private static $AjaxResponse = NULL;
	private static $Response = NULL;

	private static $Controller = NULL;
	private static $Model = NULL;
	private static $View = NULL;
	private static $namespaceBase = '';
	private static $appUrl = '';
	private static $isCalledByRequestAction = FALSE;

	private static $data = array();
	private static $params = array();
	private static $headers = array();
	private static $outputContent = NULL;
	private static $url = '';
	protected static $typeOfResponse = FALSE;
	private static $_valueType = 'assoc';

	public static $sharedVars = array();
	public static $sharedRequestVars = array();

	private function resetProperties() {
/*
		$arrayPropertiesNames = array(
										'Reflection' => NULL,
										'Cast' => NULL,
										'Http' => NULL,
										'Encrypt' => NULL,
										'Decrypt' => NULL,
										'Request' => NULL,
										'AjaxResponse',
										'Response' => NULL,
										'Controller' => NULL,
										'Model' => NULL,
										'View' => NULL,
										'namespaceBase' => NULL,
										'appUrl' => NULL,
										'data' => array(),
										'params' => array(),
										'headers' => array(),
										//'outputContent' => NULL,
										'url' => '',
										'_valueType' => 'assoc',
										'sharedVars' => array()
									);

		$arrayPropertiesNames = (array)array_diff_key((array)self::$arrayNotResetProperties, $arrayPropertiesNames);

		foreach($arrayPropertiesNames as $property => $value) {

			self::$$property = $value;
		}

		self::$arrayNotResetProperties = array();
		*/
		
		self::$Reflection						= NULL;
		self::$Cast								= NULL;
		self::$Http								= NULL;
		self::$Encrypt							= NULL;
		self::$Decrypt							= NULL;
		self::$Request							= NULL;
		self::$AjaxResponse						= NULL;
		self::$Response							= NULL;
		self::$Controller						= NULL;
		self::$Model							= NULL;
		self::$View								= NULL;
		self::$namespaceBase					= NULL;
		self::$appUrl							= NULL;
		self::$data								= array();
		self::$params							= array();
		self::$headers							= array();
		self::$url								= '';
		self::$_valueType						= 'assoc';
		self::$sharedVars						= array();
		self::$typeOfResponse					= FALSE;
		//self::$isCalledByRequestAction=FALSE;
		//self::$outputContent=NULL;
	}

	public function __sleep() {

	}

	public function __wakeup() {

		
	}

	public function __invoke() {

	}

	public function __construct($instanceOf = 'MasterObject') {

	}

	public function __destruct() {

		unset($this);
	}

	private function addObjectInStack($Object = NULL) {

		$SplStack = 'SplStack';

		if(!self::$ObjectStack instanceof $SplStack) {

			self::$ObjectStack = new \SplStack();
		}

		if(self::$ObjectStack->count() > 0) {

			self::$headers = headers_list();
			$ReflectionObject = new \Core\Libs\Reflection\ReflectionObject(new MasterObject());
			self::$ObjectStack->push($ReflectionObject->getPropertiesRecursive());
			$this->resetProperties();
		}

		else {

			self::$ObjectStack->push('initialized');
			return FALSE;
		}
	}

	private function removeObjectInStack($Object = NULL) {

		$count = self::$ObjectStack->count();

		if($count > 1) {

			$content = self::$outputContent;
			$ReflectionObject = new \Core\Libs\Reflection\ReflectionObject(new MasterObject());
			$ReflectionObject->mergePropertiesRecursive(self::$ObjectStack->top());
			self::getResponse()->ResponseHeader()->restoreHeaders(self::$headers, TRUE);
			self::$outputContent = $content;
			unset($content);
		}

		if($count > 0) {

			self::$ObjectStack->pop();
		}
	}

	final public static function getObjectStack() {

		$SplStack = 'SplStack';

		if(!self::$ObjectStack instanceof $SplStack) {

			self::$ObjectStack = new \SplStack();
		}

		return self::$ObjectStack;
	}

	final public static function setTypeOfResponse($type = 'responseOfView') {

		self::$typeOfResponse = $type;
	}

	final public static function getTypeOfResponse() {

		return self::$typeOfResponse;
	}

	final public static function setNamespaceBase($namespaceBase) {

		self::$namespaceBase = $namespaceBase;
	}

	final public static function getNamespaceBase() {

		return self::$namespaceBase;
	}

	final public static function setUrl($url) {

		self::$url = $url;
	}

	final public static function getUrl($full = FALSE) {

		if($full === FALSE) {

			return self::$url;
		}

		return HTTP_HOST . self::$url;
	}

	private static function setAppUrl($url = NULL) {

		if(empty($url)) {

			$url = self::$namespaceBase;
		}

		self::$appUrl = str_replace('\\', '/', $url);
	}

	final public static function getAppUrl() {

		return self::$appUrl;
	}

	final public function isValidAction($action) {

		if(preg_match('/[^a-zA-Z]/', $action{0})) {

			throw \Core\Uses\Exception('Erro: Nome inválido para Action do Controller/View (Deve-se iniciar com letras de a-zA-Z ou _). - Action: ' . $action);
		}

		else {

			return TRUE;
		}
	}

	final public function setIsCalledByRequestAction($isCalledByRequestAction = TRUE) {

		self::$isCalledByRequestAction = $isCalledByRequestAction;
	}

	final public function isCalledByRequestAction() {

		return self::$isCalledByRequestAction;
	}

	public function setOutputContent($outputContent = NULL) {

		self::$outputContent = $outputContent;
	}

	public function getOutputContent() {

		return self::$outputContent;
	}

	final public static function requestAction($string, $arrayConfig = array(), $noReset = FALSE) {

		$match = array();

		if($string{0} === '/') {

			$string =& substr(&$string, 1);
		}

		preg_match('/^([a-zA-Z0-9\_\.]+)?(?(1)(\:\:))/', &$string, $match);

		if($match[2] === '::') {

			$string =& preg_replace('/\:\:/', '/', &$string, 1);
		}

		if($string{0} !== '/') {

			$string = '/' . $string;
		}
/*
		$arrayReturnType = (array)array_intersect(array('returnOfController', 'responseOfController', 'returnOfView', 'responseOfView', 'responseOfRequest'), (array)$arrayConfig);
		$arrayReturnType = end($arrayReturnType);

		if(!empty($arrayReturnType)) {

			self::$typeOfResponse = $arrayReturnType;
		}

		else {

			self::$typeOfResponse = 'responseOfRequest';
		}

		$Response = self::getResponse();
		$Response->setContentToResponseOfRequest(self::$typeOfResponse);
		$containerType = $Response->getContainerTypeToResponse();
		$typeOfResponse = self::$typeOfResponse;

		if(empty($containerType)) {

			$Response->setContainerTypeToResponse(self::$typeOfResponse);
		}

		if(in_array('sendAll', (array)$arrayConfig)) {

			$Response->setAllContentToResponseOfRequest(TRUE);
		}

		else {

			$Response->setAllContentToResponseOfRequest(FALSE);
		}*/

		self::$isCalledByRequestAction = TRUE;
		$Dispatcher = new \Core\Libs\Dispatcher\Dispatcher();
		$Dispatcher->dispatch($string, $arrayConfig);
		$outputContent = NULL;
		//self::$typeOfResponse = FALSE;
		self::$isCalledByRequestAction = FALSE;

		//$Response->setStream(ob_get_clean());
		//return ob_get_contents();
		unset($Dispatcher);
		$content = self::$outputContent;
		self::$outputContent = NULL;

		return $content;
	}

	private static function getMethodsAllowed() {

		return self::$arrayMethodsAllowed;
	}

	private static function addMethodsAllowed($arrayMethods) {

		if(is_array(&$arrayMethods) && count(&$arrayMethods) > 0) {

			self::$arrayMethodsAllowed =& array_merge_recursive(&self::$arrayMethodsAllowed, &$arrayMethods);
		}
	}

	private static function namespaceForMethodPermittedExists($namespace) {

		if($namespace{0} === '\\') {

			$namespace = substr($namespace, 1);
		}

		return array_key_exists(&$namespace, &self::$arrayMethodsAllowed);
	}

	private static function isMethodAllowed($namespace, $method) {

		if($namespace{0} === '\\') {

			$namespace = substr($namespace, 1);
		}

		if(is_array(&self::$arrayMethodsAllowed[$namespace])) {

			return in_array(&$method, &self::$arrayMethodsAllowed[$namespace]);
		}

		return FALSE;
	}

	final public static function getSoapServer() {

		
	}

	final public static function getSoapClient() {

		
	}

	final public static function getSocketServer() {

		
	}

	final public static function getSocketClient() {

		
	}

	final public static function getHttp() {

		if(empty(self::$Http)) {

			self::$Http = new \Core\Libs\Http\Http();
		}

		return self::$Http;
	}

	final public static function getRequest() {

		if(empty(self::$Request)) {

			self::$Request = new \Core\Libs\Request\Request();
		}

		self::$Request->__construct();
		return self::$Request;
	}

	final public static function getMessage($id = NULL, $type = 'send') {

		if(empty(self::$Message)) {

			self::$Message =& \Core\Libs\JabezSingleton\jabezSingleton::loadInstance('Core\Libs\Message\Message', TRUE, TRUE, TRUE, FALSE, array($id, $type));
		}

		else {

			self::$Message->__construct($id, $type);
		}

		return self::$Message;
	}

	final public static function getResponse() {

		if(empty(self::$Response)) {

			self::$Response = new \Core\Libs\http\Response();
		}

		return self::$Response;
	}

	final public static function getAjaxResponse($jsonResponse = TRUE, $jsonConfig = NULL) {

		if(empty(self::$AjaxResponse)) {

			self::$AjaxResponse = new \Core\Libs\http\AjaxResponse($jsonResponse, $jsonConfig);
		}

		return self::$AjaxResponse;
	}

	final public static function &setRegistry($Registry = NULL) {

		self::$Registry = $Registry;
	}

	final public static function getRegistry() {

		return self::$Registry;
	}

	final public static function &setReflection($Reflection = NULL) {

		self::$Reflection = $Reflection;
	}
/*
	final public static function getReflection() {

		return self::$Reflection;
	}
*/	
	final public static function getReflection($nameSpace = NULL, $object = FALSE, $reset = TRUE) {
	
	  	return new \Core\Libs\Reflection\ReflectionClass($nameSpace, $object, $reset);
	}
	final public static function getCast($param = NULL) {

		if(empty(self::$Cast)) {

			self::$Cast = new \Core\Libs\Cast\Cast();
		}

		if(func_num_args() > 0) {

			self::$Cast->__construct($param);
		}

		else {

			self::$Cast->__construct();
		}

		return self::$Cast;
	}

	final public static function &setView($View = NULL, $namespace = NULL) {

		if(!empty($View)) {

			self::$View = $View;
		}
	}

	final public static function &setModel($Model = NULL) {

		self::$Model = $Model;
	}

	final public static function &getModel() {

		return self::$Model;
	}

	final public static function &getView() {

		return self::$View;
	}

	final public static function &setController($Controller = NULL) {

		if(!empty($Controller)) {

			self::$Controller = $Controller;
		}
	}

	final public static function getController() {

		return self::$Controller;
	}

	final public static function &_addData($data = array()) {

		self::$data =& array_merge((array)self::$data, (array)$data);
	}

	final public static function &_setData($data = array()) {

		self::$data = $data;
	}

	final public static function &getData($idRequest = NULL) {

		if(!empty($idRequest)) {

			$idRequest =& str_replace('\\', '.', &$idRequest);

			if($idRequest{0} === '.') {

				$idRequest =& substr(&$idRequest, 1);
			}

			if(array_key_exists(&$idRequest, self::$data)) {

				return self::$data[$idRequest];
			}

			else {

				return array();
			}
		}

		return self::$data;
	}

	final public function &getParams($type = NULL) {

		if($type !== NULL) {

			self::$_valueType =& $type;
		}

		else {

			return self::getRequest()->getElement(array('params'));
		}

		return $this;
	}

	final public static function &getValue($id = NULL) {

		if(!is_null(&$id)) {

			return self::getRequest()->getElement(array('params', self::$_valueType, $id));
		}

		return NULL;
	}

	final public static function &getValues() {

		return self::getRequest()->getElement(array('params', self::$_valueType));
	}

	final public static function &setParams($params = array()) {

		self::getRequest()->addElement(array('params'), $params);
	}

	final public static function &addParams($params = array()) {

		self::getRequest()->addElement(array('params', 'numeric'), (array)$params['numeric'] + (array)self::getRequest()->getElement(array('params', 'numeric')));
		self::getRequest()->addElement(array('params', 'assoc'), (array)$params['assoc'] + (array)self::getRequest()->getElement(array('params', 'assoc')));
	}

	final public static function _stop($status = 0) {

		exit($status);
	}

	final public static function _return() {

		
	}
}
?>